from time import sleep
import re

from qturboframe.lib.utils.by import By
from qturboframe.lib.report.log import logger
from qturboframe.lib.utils.check import CheckBasic
from qturboframe.lib.webdriver.exceptions import SeleniumError

from .base_element import BaseElement


class Button(BaseElement, CheckBasic):
    '''
    jres2.0的按钮操作

    :Attributes:
     - _driver: 控件所在的当前webdriver对象
     - _element: 控件元素webelement对象
     - timeout: 步骤操作的超时时间

    Raises:
        当以文本找不到对应button时则抛出SeleniumError异常

    :Example:
     - 例1: Button(webelement)
     - 例2: Button('登录')
     - 例3: Button({By.NAME:'name'})
     - 例4: Button({By.CLASS_NAME:'class_name','text':'文本信息'})
     - 例5: Button({By.CLASS_NAME:'class_name','text':'文本信息'}, father=driver)
     - 例6: Button({By.CLASS_NAME:'class_name','text':'文本信息'}, father=webelement)
    '''

    def __init__(self, element_para, father=None, timeout=5):
        if isinstance(element_para, str):
            xpath_button = ".//button[normalize-space(text())='{}' and not(contains(@style,'display: none'))]".format(element_para)
            xpath_a = ".//a[normalize-space(string())='{}' and not(contains(@style,'display: none')) or normalize-space(@title)='{}']".format(element_para, element_para)
            xpath_span = ".//span[@title='{}' or normalize-space(text())='{}']".format(element_para, element_para)
            xpath = xpath_button + " | " + xpath_a + " | "+xpath_span
            button = father.find_first_displayed_element("xpath", xpath, timeout=timeout)
            if button:
                super().__init__(button, father, timeout)
                return

            raise SeleniumError("没有找到名字为'{}'的按钮".format(element_para))
        elif isinstance(element_para, dict) and By.TEXT in element_para:
            xpath_button = ".//button[normalize-space(text())='{}' and not(contains(@style,'display: none'))]".format(element_para.get(By.TEXT))
            xpath_a = ".//a[contains(normalize-space(string()),'{}') and not(contains(@style,'display: none')) or normalize-space(@title)='{}']".format(element_para.get(By.TEXT),element_para.get(By.TEXT))
            xpath_span = ".//span[@title='{}' or normalize-space(text())='{}']".format(element_para.get(By.TEXT), element_para.get(By.TEXT))
            xpath_input = ".//input[@value='{}']".format(element_para.get(By.TEXT))
            xpath = xpath_button + " | " + xpath_a + " | " + xpath_span + " | " + xpath_input
            buttons = father.find_elements_by_attribute(By.XPATH, xpath, timeout=timeout)
            # 过滤出可见的button
            displayed_buttons = []
            for btn in buttons:
                if btn.is_displayed():
                    displayed_buttons.append(btn)
            self.buttons = displayed_buttons
            if len(buttons) != 0:
                super().__init__(self.buttons[0], father, timeout)
                return

            raise SeleniumError("没有找到名字为'{}'的按钮".format(element_para))
        else:
            super().__init__(element_para, father, timeout)
            self.buttons = self._elements

    def click(self):
        '''
        jres2.0的按钮点击

        :Returns:
            可用则返回True, 不可用则返回False

        :Example:
         - 例: button.click()
        '''
        button_text = self._element.text
        if not button_text:
            button_text = self._element.get_attribute('title')
        logger.info('点击按钮：' + button_text)
        self._element.secure_click()

    def js_click(self, index=1):
        '''
        点击元素

        :Example:
         - 例: base_element.click()
        '''
        if index == 1:
            self._driver.execute_script("arguments[0].click();", self._element)
        else:
            self._driver.execute_script("arguments[0].click();", self.buttons[index-1])

    def dropdown_click(self, dropdown_text):
        '''
        jres2.0的dropdown按钮点击

        :Args:
         - dropdown_text: dropdown按钮的文本

        :Example:
         - 例: button.dropdown_click('删除')
        '''
        button_text = self._element.text
        logger.info('点击按钮：' + button_text)
        # 查找按钮组件
        select_father_div = self._element.find_element_by_attribute(
            'xpath', './parent::div/parent::div', timeout=0.1)
        self._element.secure_click()
        timeout = 0
        while timeout < self.timeout:
            # 保持鼠标悬停在按钮上
            self._element.move_to()
            # 查找下拉按钮
            select_li_btn = select_father_div.exist(
                'css selector', 'li.h-dropdown-item', 'text:' + dropdown_text, timeout=0.1)
            if select_li_btn:
                break
            else:
                timeout += 0.1
                sleep(0.1)
        else:
            raise SeleniumError('未找到按钮：{}！'.format(dropdown_text))
        logger.info('点击按钮：' + dropdown_text)
        select_li_btn.secure_click()

    def is_enable(self):
        '''
        判断jres2.0按钮是否可用

        :Returns:
            可用则返回True, 不可用则返回False

        :Example:
         - 例: button.is_enable()
        '''
        if self._element.is_enabled():
            return True
        else:
            return False

    def check_enable(self, state='disable'):
        '''
        jres2.0按钮是否可用校验

        :Attributes:
         - flag: 校验标记，表示需要校验的按钮状态，display表示禁用，enable表示可用

        :Raises:
            不可用则抛出SeleniumError异常

        :Example:
         - 例: button.check_enable('enable')
        '''
        if state == 'disable':
            if self._element.is_enabled():
                raise SeleniumError('按钮未禁用！')
        else:
            if not self._element.is_enabled():
                raise SeleniumError('按钮已禁用！')
